package com.violet.myorm.core.execute;

import com.violet.myorm.core.combination.UpdateCombination;
import com.violet.myorm.core.condition.LambdaWhere;
import com.violet.myorm.core.condition.SerializableFunction;
import com.violet.myorm.core.source.Reflect;
import com.violet.myorm.core.sql.UpdateSql;
import com.violet.myorm.utils.SqlUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class Update<E>
    extends BaseExecute
    implements UpdateCombination<E, Update<E>>
{
    private final Class<?> clazz;
    private final List<String> fields;
    private final List<Object> values;
    private final String primaryKeyName;
    private LambdaWhere<E> where;

    public Update(Class<E> clazz) {
        this.clazz = clazz;
        this.where = new LambdaWhere<>();
        this.fields = new ArrayList<>();
        this.values = new ArrayList<>();
        this.primaryKeyName = Reflect.getFieldName(Reflect.getPrimaryKey(clazz));
    }

    @Override
    public Update<E> where(LambdaWhere<E> condition) {
        where = condition;
        return this;
    }

    @Override
    public int executeUpdate() {
        UpdateSql update = SqlUtils.createUpdate(clazz, fields, where.getWhere());
        return executeUpdate(update, values, where.getWhereParams());
    }

    @Override
    public <T> Update<E> set(SerializableFunction<E, ?> function, T value) {
        return set(Reflect.getNormName(function.getName()), value);
    }

    @Override
    public Update<E> set(String fieldName, Object value) {
        if (primaryKeyName.equals(fieldName)) return this;
        fields.add(fieldName);
        values.add(value);
        return this;
    }
}
